// 引入 axios
import axios from 'axios'
import store from '@/store'
import { Message } from 'element-ui'
import router from '@/router'
import qs from 'qs'

// axios.create() 使用自定义配置新建一个 axios 实例
const request = axios.create({})
// 封装 url 及地址检测函数
function getBaseUrl (url) {
  if (url.startsWith('/boss')) {
    return 'http://eduboss.lagou.com'
  } else {
    return 'http://edufront.lagou.com'
  }
}
// 添加请求拦截
request.interceptors.request.use(function (config) {
  // 基地址处理
  config.baseURL = getBaseUrl(config.url)
  // 设置统一 token后,才能访问后台数据
  const { user } = store.state
  if (user && user.access_token) {
    config.headers.Authorization = user.access_token
  }
  return config
}, function (error) {
  return Promise.reject(error)
})
// 封装跳转登录页面函数
function redirectLogin () {
  router.push({
    name: 'login',
    query: {
      // router.currentRoute 获取当前路由对应的路由信息对象
      redirect: router.currentRoute.fullPath
    }
  })
}
// 是否正在更新 token
let isRefreshing = false
// 存储因等待 Token 刷新而挂起的请求
let requests = []

// 响应拦截
request.interceptors.response.use(function (response) {
  // 状态码为 2xx 进入这里
  return response
}, function (error) {
  if (error.response) {
    //  超出 2xx 进入这里(常见错误处理位置)
    // 1.保存状态码
    const { status } = error.response
    // 2.判断
    let errMessage = ''
    if (status === 400) {
      errMessage = '请求参数错误'
    } else if (status === 401) {
      // token无效
      // 1.检测:如果 store 不存在 user,跳转登录页
      if (!store.state.user) {
        // 调用跳转登录页面函数
        redirectLogin()
        return Promise.reject(error)
      }
      if (isRefreshing) {
        return requests.push(() => {
          request(error.config)
        })
      }
      isRefreshing = true
      // 2.根据 refresh_token 请求新的 access_token
      return request({
        method: 'POST',
        url: '/front/user/refresh_token',
        data: qs.stringify({
          refreshtoken: store.state.user.refresh_token
        })
      }).then(res => {
        // 检测是否成功请求到新的 access_token
        // 1.没有请到新的 access_token,跳转回登录页
        if (res.data.state !== 1) {
          // 清除已经无效的用户信息
          store.commit('setUser', null)
          // 调用跳转登录页面函数
          redirectLogin()
          return Promise.reject(error)
        }
        // 2.如果成功,将新的 access_token 更新到容器与本地存储中
        store.commit('setUser', res.data.content)
        requests.forEach(callback => callback())
        requests = []
        return request(error.config)
      }).catch(() => {
        store.commit('setUser', null)
        // 调用跳转登录页面函数
        redirectLogin()
        return Promise.reject(error)
      }).finally(() => {
        isRefreshing = false
      })
    } else if (status === 403) {
      errMessage = '没有访问权限,请联系管理员'
    } else if (status === 404) {
      errMessage = '请求资源不存在'
    } else if (status >= 500) {
      errMessage = '服务端错误,请联系管理员'
    }
    Message.error(errMessage)
  } else if (error.request) {
    // 请求发送成功,但没有响应
    Message.error('请求超时,请重试')
  } else {
    // 在设置请求时发生了一些失去,出发了错误(未知性错误)
    Message.error(`请求失败${error.message}`)
  }
  return Promise.reject(error)
})

export default request
